#include "server.h"
#include "framework.h"
#include "commonfunc.h"
#include "cnsGlobal.h"
#include "sysserversocket.h"
#include "sysserverheartbeat.h"
#include "syssqlinterpreter.h"
#include "dbquerythread.h"
#include "systhreadpool.h"
#include "sysloginserv.h"
#include "syshttpserv.h"
#include "gn_viewer/sysgnfindpathmodel.h"
#include "gn_viewer/gnfindpaththread.h"
#include "sysinitdb.h"
#include "dbqueriesthread.h"
#include "sysreadsqlsandsplit.h"
#include "gn_viewer/gnfindpathdbthread.h"

CNS_SYS_REGISTER(SysServerHeartbeat)
CNS_SYS_REGISTER(SysSqlInterpreter)
CNS_SYS_REGISTER(SysDbQueryThread)
CNS_SYS_REGISTER(SysThreadPool)
CNS_SYS_REGISTER(SysLoginServ)
CNS_SYS_REGISTER(SysHttpServ)
CNS_SYS_REGISTER(SysGnFindPathModel)
CNS_SYS_REGISTER(SysGnFindPathThread)
CNS_SYS_REGISTER(SysInitDb);
CNS_SYS_REGISTER(SysDbQueriesThread)
CNS_SYS_REGISTER(SysReadSqlsAndSplit)
CNS_SYS_REGISTER(SysGnFindPathDBThread)

Framework *g_fwServer = nullptr;

Server::Server()
{
    start();
}

void Server::close()
{
    native::stop();
    uv_async_send(_server->getAsync());
    quit();
}

Server::~Server()
{
    delete _loopTimer;
}

void Server::run()
{
    _loop = uv_loop_new();
    _loopTimer = new QTimer();
    connect(_loopTimer, &QTimer::timeout, _loopTimer, [this](){
        uv_run(_loop, UV_RUN_NOWAIT);
    });
    _loopTimer->setInterval(100);
    _loopTimer->start();
    FRAMEWORK = new Framework();
    FRAMEWORK->readComDefinition("cns/server");
    CnsComponentPtr httpServ = FRAMEWORK->getComponent("/server/.//httpServer");
//    httpServ->moveToThread(currentThread());
    bool ret;
    httpServ->exec("start", QStringList(), Qt::DirectConnection,
               Q_RETURN_ARG(bool, ret));
    if(!ret) return;
    _server = FRAMEWORK->newComponent("serverSocket", "/server/.//serverSocket").staticCast<ServerSocketProc>();
//    bool ret;
    ret = false;
    _server->exec("start", QStringList(), Qt::DirectConnection,
               Q_RETURN_ARG(bool, ret));
    if(!ret) return;
    _server->exec("run", Q_ARG(uv_loop_t*, _loop));
    exec();

    SYS(SysServerSocket)->server_destroy(_server.data());
    uv_loop_close(_loop);
    free(_loop);
}
